home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Applications / NeuroSim 1.0 / Slider ƒ / Slider.cp next >
Text File  |  1996-02-19  |  28KB  |  925 lines

  1. // 
  2. // ===========================================================================
  3. //     Slider.cp                        ©1994 Scott Squires  
  4. // ===========================================================================
  5. //
  6.  
  7. // ***
  8. // *** NOTE: The HorzSlider::GetSliderValue function has been MODIFIED.
  9. // ***       I'm distributing this modified version with Scott's permission.
  10. // ***
  11. // ***                                Timo Eloranta (02/19/1996)
  12. // ***
  13.  
  14. /*
  15. HorzSlider and VertSlider are classes for PowerPlant that provide a movable
  16. slider similar to setting the volume control on the Mac.  I wrote these classes
  17. over a year ago with CW DR1 or 2.
  18.  
  19. Rather than dealing with CDEFs these classes can be compiled and used directly in
  20. your program and easily subclassed or modified for new behavior.  This makes
  21. tracking action very easy.
  22.  
  23. I'm posting this as freeware (but still copyrighted) for people to use as they
  24. like.
  25.  
  26. Scott Squires
  27.     Internet: squires@crl.com
  28.     AOL: ScottSquir 
  29.     CompuServe: 76545,573
  30.  
  31.  
  32. Usage:
  33.  
  34. Create a Base or background picture for your slider and save it as a PICT
  35. resource. Create a Slider picture for your slider and save it as a PICT resource.
  36. This should be smaller than your base picture.
  37.  
  38.  
  39. PPob Version:
  40.  
  41.     Using Window PPob with Slider built in:
  42.     
  43.     Create Window/view PPob with subviews of Hsld or Vsld.  You can do this in
  44.     PowerPlant Constructor by creating a view and changing it's type name to
  45.     Hsld or Vsld.
  46.     
  47.         // In App constructor register these classes
  48.         URegistrar::RegisterClass(HorzSlider::class_ID, HorzSlider::CreateHorzSliderStream);
  49.         URegistrar::RegisterClass(VertSlider::class_ID, VertSlider::CreateVertSliderStream);
  50.  
  51.         // after loading a PPob window with Sliders
  52.         HorzSlider * theSlider = (HorzSlider *)theView->FindPaneByID(2006);
  53.          theSlider->SetPicts(128,129);        // Pict ResID 128 is base
  54.                                              // Pict ResID 129 is slider
  55.         theSlider->SetMinMax(0,1000);        // sets value range
  56.          theSlider->SetValueMessage(2006);    // In your view listen for this msg
  57.  
  58.         if (theSlider->MakeSlider())        // Do the actual building of slider
  59.             theSlider->AddListener(theView);
  60.         else
  61.             delete theSlider;                    // delete if couldn't be created
  62.  
  63.  
  64.  
  65. Run Time Version:
  66.     // assumes you've created window and theView
  67.     HorzSlider *theSlider = new HorzSlider(128,129);    // Pict ResID 128 is base
  68.                                                         // Pict ResID 129 is slider
  69.     theSlider->PutInside(theView);
  70.      theSlider->SetMinMax(0,1000);        // sets value range
  71.       theSlider->SetValueMessage(2006);    // In your view listen for this msg
  72.  
  73.         if (theSlider->MakeSlider())    // Do the actual building of slider
  74.             theSlider->AddListener(theView);
  75.         else
  76.             delete theSlider;                    // delete if couldn't be created
  77.  
  78.  
  79.  
  80.  // In your view/listener do something like this:
  81.      void MyView::ListenToMessage(MessageT inMessage, void *ioParam)
  82.     {
  83.          switch (inMessage) {
  84.             // Message sent from Slider when value is updated
  85.              
  86.         case 2006:
  87.              NumToString(*(long *)ioParam, theNum);
  88.             SetRect(&box, 215, 10, 245, 30);
  89.             TextBox(theNum + 1, theNum[0], &box, teFlushRight);
  90.             break;
  91.     
  92.      }
  93.      }
  94.      
  95.      
  96.  
  97. Under the Hood:
  98.  
  99. Slider is an abstract class based on LView and LBroadcaster. HorzSlider and
  100. VertSlider are built from Slider.
  101.  
  102. When a slider object is created default values are set. During MakeSlider() the
  103. picture resources that were assigned are loaded and LGWorld objects are created
  104. to hold these pictures. If a third pict is specfied it is used as a selected
  105. slider. An additional LGWorld is created to hold the Slider image when it is
  106. updated.
  107.  
  108. The slider is resized to match the actual size of the base picture.
  109.  
  110. When a slider is clicked on the selected slider is displayed if one was
  111. specified.  The mouse is then tracked and the slider is continuously updated. For
  112. each update a Message is broadcast to any listeners with the new value.
  113.  
  114. DrawSelf() for the slider copies the GWorld with the base picture to the
  115. work GWorld.  The slider or selected slider is then copied to this as well.
  116. Finally the work GWorld is copied to the screen.
  117.  
  118.  
  119. Misc Notes:
  120.  
  121. Slider pictures are assumed to be smaller than the base pictures.
  122. Slider pictures can be offset within a base picture.
  123.  
  124. The Selected slider picture is assumed to be the same size as the normal slider.
  125. Sliders are dealt with as rectangular objects.  You can still simulate an
  126. irregular image.
  127.  
  128. Slider values are signed longs so can be quite large.
  129.  
  130. The LGWorlds are created with the deepest depth.  This allows the best speed for
  131. updates.  You could change this to 8 bits (256 colors) if memory will be tight.
  132.  
  133. If you click on the base picture and not the actual slider the slider will move
  134. instantly to that position.
  135.  
  136. Sliders have a flag that can cause the cursor to be hidden while tracking.
  137.  
  138. Sliders also have a flag that can just activate the slider, not the base picture.
  139.  
  140. Any window that Sliders are added to should be hidden until the MakeSlider() is
  141. executed.
  142.  
  143. MakeSlider() was factored out of the constructor to avoid memory problems in a
  144. constructor and to provide a little more flexibility.
  145.  
  146.  
  147. Future:
  148. Feel free to improve, subclass, or modify.
  149.  
  150. These are based on LView class to allow more flexibility but could be based on
  151. LPane without problems.
  152.  
  153. Rather than being based on LView these could be created from LControl with
  154. simularities to controls.  (min, max, values, etc)   
  155.  
  156. Slider PPobs are just LViews  renamed/typed.  As such the create from stream
  157. functions don't contain any more data than an LView would. Future versions of
  158. PowerPlant Constructor might make it easier to add the pict IDs and other values.
  159.  
  160. I had planned to implement 'dirty rectangles' to make the updates faster but that
  161. hasn't proved necessary for my uses.  This could be done by creating a function
  162. similar to DrawSelf that would be called while tracking.  Rather than copying the
  163. entire base GWorld over just the rectangle where the slider used to be would be
  164. copied to the temp GWorld.  The slider would be copied like usual and then the
  165. GWorld to window copy would only copy a rectangle that would cover the old and
  166. new slider rectangle.  (small if updated quickly)
  167.  
  168. Regions could be used for checking clicks and for copying irregular images.
  169. Create a temp GWorld 1 bit deep, draw slider pict and then use BitMapToRegion.
  170.  
  171. You could provide B&W and color picts and have correct versions loaded depending
  172. on screen depth.
  173.  
  174.  
  175. */
  176.  
  177. #include "Slider.h"
  178. #include <UGWorld.h>
  179. #include <PP_Messages.h>
  180.  
  181. // ---------------------------------------------------------------------------
  182. //        • SetDefaults
  183. // ---------------------------------------------------------------------------
  184. //    Init values in a slider
  185.  
  186.  
  187. void Slider::SetDefaults(void)
  188. {
  189.     mBasePictID = resID_Undefined;
  190.     mSliderPictID = resID_Undefined;
  191.     mSliderSelectPictID = resID_Undefined;
  192.     SetRect(&mBasePictRect, 0, 0, 100, 25);
  193.     SetRect(&mSliderRect, 0, 0, 25, 25);
  194.     mMinSliderValue = 0;
  195.     mMaxSliderValue = 100;
  196.     mSelected = false;
  197.     mSliderCursor = true;
  198.     mBaseGWorld = nil;
  199.     mSliderGWorld = nil;
  200.     mSliderSelectGWorld = nil;
  201.     mWorkGWorld = nil;
  202.     mSliderOnly = false;
  203.  
  204. }
  205.  
  206.  
  207. // ---------------------------------------------------------------------------
  208. //        • Slider
  209. // ---------------------------------------------------------------------------
  210. //    Default Constructor
  211.  
  212.  
  213. Slider::Slider()
  214. {
  215.     SetDefaults();
  216. }
  217.  
  218.  
  219. // ---------------------------------------------------------------------------
  220. //        • Slider(ResIDT mBasePictRes, ResIDT mSliderPictRes)
  221. // ---------------------------------------------------------------------------
  222. //     Create Slider and assign Pict resource numbers
  223.  
  224.  
  225. Slider::Slider(ResIDT BasePictRes, ResIDT SliderPictRes)
  226. {
  227.     SetDefaults();
  228.     mBasePictID = BasePictRes;
  229.     mSliderPictID = SliderPictRes;
  230.  
  231. }
  232.  
  233.  
  234. // ---------------------------------------------------------------------------
  235. //        • Slider(ResIDT mBasePictRes, ResIDT mSliderPictRes, ResIDT SlideSelectPictRes)
  236. // ---------------------------------------------------------------------------
  237. //     Create Slider including selected slider and assign Pict resource numbers
  238.  
  239.  
  240. Slider::Slider(ResIDT BasePictRes, ResIDT SliderPictRes, ResIDT SlideSelectPictRes)
  241. {
  242.     SetDefaults();
  243.     mBasePictID = BasePictRes;
  244.     mSliderPictID = SliderPictRes;
  245.     mSliderSelectPictID = SlideSelectPictRes;
  246.  }
  247.  
  248. // ---------------------------------------------------------------------------
  249. //        • Slider(LStream*)
  250. // ---------------------------------------------------------------------------
  251. //    Construct Slider from data in a Stream
  252.  
  253. Slider::Slider(LStream *inStream)
  254.     : LView(inStream)
  255.     {
  256.     SetDefaults();
  257.     }
  258.  
  259.  
  260. // ---------------------------------------------------------------------------
  261. //        • ~Slider
  262. // ---------------------------------------------------------------------------
  263. //    Destructor, deletes any LGWorld objects created
  264.  
  265.  
  266. Slider::~Slider(void)
  267. {
  268.     if (mBaseGWorld)
  269.         delete mBaseGWorld;
  270.     if (mWorkGWorld)
  271.         delete mWorkGWorld;
  272.     if (mSliderGWorld)
  273.         delete mSliderGWorld;
  274.     if (mSliderSelectGWorld)
  275.         delete mSliderSelectGWorld;
  276. }
  277.  
  278. // ---------------------------------------------------------------------------
  279. //        • MakeSlider
  280. // ---------------------------------------------------------------------------
  281. //    Loads PICT resources, creates LGWorlds, and draw pictures into LGWorlds
  282.  
  283. Boolean Slider::MakeSlider(void)
  284. {
  285.     PicHandle macPictureH = ::GetPicture(mBasePictID);
  286.     if (macPictureH != nil) {                         // Use PICT if found
  287.          mBasePictRect = (*macPictureH)->picFrame;
  288.         OffsetRect(&mBasePictRect, -mBasePictRect.left, -mBasePictRect.top);
  289.         mBaseLength = mBasePictRect.right;
  290.         mBaseHeight = mBasePictRect.bottom;
  291.                                                     // Adjust Pane size
  292.         ResizeFrameTo(mBasePictRect.right, mBasePictRect.bottom, false);
  293.  
  294.         mBaseGWorld = new LGWorld(mBasePictRect, 0, 0, 0, 0);        // Make GWorld
  295.  
  296.         if (mBaseGWorld) {                                // draw the picture
  297.             mBaseGWorld->BeginDrawing();
  298.             ::DrawPicture(macPictureH, &mBasePictRect);
  299.             mBaseGWorld->EndDrawing();
  300.  
  301.             mWorkGWorld = new LGWorld(mBasePictRect, 0, 0, 0, 0);
  302.  
  303.             if (mWorkGWorld) {
  304.                 mWorkGWorld->BeginDrawing();
  305.                 ::DrawPicture(macPictureH, &mBasePictRect);
  306.                 mWorkGWorld->EndDrawing();
  307.             }
  308.           }
  309.         ReleaseResource( (Handle)macPictureH ); 
  310.     }
  311.  
  312.     // Get Slider picture and make LGWorld
  313.     macPictureH = ::GetPicture(mSliderPictID);
  314.     if (macPictureH != nil) {
  315.          mSliderRect = (*macPictureH)->picFrame;
  316.         OffsetRect(&mSliderRect, -mSliderRect.left, -mSliderRect.top);
  317.         
  318.         mBaseLength = mBaseLength -  (mSliderRect.right - mSliderRect.left);
  319.         mBaseHeight = mBaseHeight -  (mSliderRect.bottom - mSliderRect.top);
  320.         mSliderGWorld = new LGWorld(mSliderRect, 0, 0, 0, 0);
  321.          if (mSliderGWorld) {
  322.             mSliderGWorld->BeginDrawing();
  323.             ::DrawPicture(macPictureH, &mSliderRect);
  324.             mSliderGWorld->EndDrawing();
  325.              
  326.         }
  327.         ReleaseResource( (Handle)macPictureH ); 
  328.     }
  329.  
  330.     if (mSliderSelectPictID != resID_Undefined)    // load and setup Selected pict if defined
  331.     {
  332.         macPictureH = ::GetPicture(mSliderSelectPictID);
  333.         if (macPictureH != nil) {
  334.  
  335.             mSliderSelectGWorld = new LGWorld(mSliderRect, 0, 0, 0, 0);
  336.              if (mSliderSelectGWorld) {
  337.                 mSliderSelectGWorld->BeginDrawing();
  338.                 ::DrawPicture(macPictureH, &mSliderRect);
  339.                 mSliderSelectGWorld->EndDrawing();
  340.             }
  341.              ReleaseResource( (Handle)macPictureH ); 
  342.         }
  343.  
  344.     }
  345.     // true if all needed picts found and GWorlds created
  346.       
  347.     return ((mBaseGWorld && mSliderGWorld && mWorkGWorld)
  348.       && ((mSliderSelectPictID == resID_Undefined) || mSliderSelectGWorld));
  349.      
  350.  
  351. }
  352.  
  353.  
  354. // ---------------------------------------------------------------------------
  355. //        • SetPicts
  356. // ---------------------------------------------------------------------------
  357. //    Defines PICT resource numbers for base and slider, no Selected slider
  358.  
  359. void Slider::SetPicts(ResIDT BasePictRes, ResIDT SliderPictRes)
  360. {
  361.     mBasePictID = BasePictRes;
  362.     mSliderPictID = SliderPictRes;
  363.  
  364. }
  365.  
  366. // ---------------------------------------------------------------------------
  367. //        • SetPicts
  368. // ---------------------------------------------------------------------------
  369. //    Defines PICT resource numbers for base, slider, and Selected slider
  370.  
  371. void Slider::SetPicts(ResIDT BasePictRes, ResIDT SliderPictRes, ResIDT SlideSelectPictRes)
  372. {
  373.  
  374.     mBasePictID = BasePictRes;
  375.     mSliderPictID = SliderPictRes;
  376.     mSliderSelectPictID = SlideSelectPictRes;
  377.  
  378. }
  379.  
  380.  
  381. // ---------------------------------------------------------------------------
  382. //        • OffsetSlider
  383. // ---------------------------------------------------------------------------
  384. //    Move Slider relative to base picture.  Used when slider is smaller tan base picture
  385.  
  386. void Slider::OffsetSlider(short Xoffset, short Yoffset)
  387. {
  388.     OffsetRect(&mSliderRect, Xoffset, Yoffset);
  389.  
  390. }
  391.  
  392.  
  393. // ---------------------------------------------------------------------------
  394. //        • DrawSelf
  395. // ---------------------------------------------------------------------------
  396. //    Draw the Slider
  397.  
  398. void Slider::DrawSelf()
  399. {
  400.     GrafPtr savePort;
  401.     GetPort(&savePort);
  402.     ::PenNormal();
  403.  
  404.     if (mBaseGWorld && mWorkGWorld) {
  405.         // copy base GWorld to temp GWorld
  406.  
  407.         mWorkGWorld->BeginDrawing();
  408.         mBaseGWorld->CopyImage((GrafPtr)mWorkGWorld->GetMacGWorld(), mBasePictRect, srcCopy, 0);
  409.         mWorkGWorld->EndDrawing();
  410.     }
  411.     if (mSelected && mSliderSelectGWorld)        // Is it selected and does a Select LGWorld exist?
  412.     {
  413.         if (mSliderSelectGWorld && mWorkGWorld) {
  414.             // copy Select slider GWorld to temp GWorld
  415.             mWorkGWorld->BeginDrawing();
  416.             mSliderSelectGWorld->CopyImage((GrafPtr)mWorkGWorld->GetMacGWorld(), mSliderRect, srcCopy, 0);
  417.             mWorkGWorld->EndDrawing();
  418.         }
  419.     } else {
  420.         if (mSliderGWorld && mWorkGWorld) {
  421.             // copy slider GWorld to temp GWorld
  422.             mWorkGWorld->BeginDrawing();
  423.             mSliderGWorld->CopyImage((GrafPtr)mWorkGWorld->GetMacGWorld(), mSliderRect, srcCopy, 0);
  424.             mWorkGWorld->EndDrawing();
  425.         }
  426.     }
  427.  
  428.     if (mWorkGWorld) {
  429.         mWorkGWorld->CopyImage(savePort, mBasePictRect, srcCopy, 0);// display it
  430.     } else {
  431.         FrameRect(&mBasePictRect);                // If all else fails, draw a box
  432.  
  433.     }
  434. }
  435.  
  436.  
  437. // ---------------------------------------------------------------------------
  438. //        • PointInSlider
  439. // ---------------------------------------------------------------------------
  440. //    Check to see if a point is within the slider rect
  441.  
  442. Boolean Slider::PointInSlider(Point thePoint)
  443. {
  444.     return (PtInRect(thePoint, &mSliderRect));
  445.  
  446. }
  447.  
  448.  
  449.  
  450.  
  451.  
  452. // ---------------------------------------------------------------------------
  453. //        • SetMinMax
  454. // ---------------------------------------------------------------------------
  455. //    Set min and max values for slider, long values
  456.  
  457. void Slider::SetMinMax(long theMin, long theMax)
  458. {
  459.     mMinSliderValue = theMin;
  460.     mMaxSliderValue = theMax;
  461.     if(IsVisible())
  462.     {
  463.         SetSliderValue(mValue);        // clamp existing value and redraw
  464.      }
  465. }
  466.  
  467.  
  468.  
  469.  
  470.  
  471. // ---------------------------------------------------------------------------
  472. //        • DoAction
  473. // ---------------------------------------------------------------------------
  474. //    Send message if new value
  475.  
  476. void Slider::DoAction(void)
  477. {
  478.     long tempValue;
  479.  
  480.     tempValue = GetSliderValue();
  481.     if (mValue != tempValue) {
  482.         // only send message if true value changed
  483.         mValue = tempValue;
  484.         BroadcastValueMessage();
  485.     }
  486.  
  487. }
  488.  
  489.  
  490. // ---------------------------------------------------------------------------
  491. //        • BroadcastValueMessage
  492. // ---------------------------------------------------------------------------
  493. //    Send message with value
  494.  
  495.  
  496. void Slider::BroadcastValueMessage()
  497. {
  498.     if (mValueMessage != cmd_Nothing) {
  499.         Int32 value = mValue;
  500.         BroadcastMessage(mValueMessage, (void *) & value);
  501.     }
  502. }
  503.  
  504.  
  505. // ---------------------------------------------------------------------------
  506. //        • SetValueMessage
  507. // ---------------------------------------------------------------------------
  508. //    Assign Message number
  509.  
  510. void Slider::SetValueMessage(MessageT inValueMessage)
  511. {
  512.     mValueMessage = inValueMessage;
  513. }
  514.  
  515.  
  516. // ---------------------------------------------------------------------------
  517. //        • GetValueMessage
  518. // ---------------------------------------------------------------------------
  519. //    Return Message number
  520.  
  521. MessageT Slider::GetValueMessage() const
  522. {
  523.     return mValueMessage;
  524. }
  525.  
  526.  
  527. // ---------------------------------------------------------------------------
  528. //        • SetCursorFlag
  529. // ---------------------------------------------------------------------------
  530. //    If true then display cursor, false hides cursor when tracking
  531.  
  532. void Slider::SetCursorFlag(Boolean theFlag)
  533. {
  534.     mSliderCursor = theFlag;
  535. }
  536.  
  537.  
  538. // ---------------------------------------------------------------------------
  539. //        • SetSliderOnlyFlag
  540. // ---------------------------------------------------------------------------
  541. //    If true then activate only when slider hit, false makes the whole base pciture active
  542.  
  543. void Slider::SetSliderOnlyFlag(Boolean theFlag)
  544. {
  545.     mSliderOnly = theFlag;
  546. }
  547.  
  548.  
  549. // ---------------------------------------------------------------------------
  550. //        • HorzSlider
  551. // ---------------------------------------------------------------------------
  552. //    Default Constructor
  553.  
  554. HorzSlider::HorzSlider()
  555.     : Slider()
  556.     {
  557.  
  558.     }
  559.  
  560. // ---------------------------------------------------------------------------
  561. //        • HorzSlider(ResIDT BasePictRes, ResIDT mSliderPictRes)
  562. // ---------------------------------------------------------------------------
  563. //     Create Horizontal Slider and assign Pict resource numbers
  564.  
  565. HorzSlider::HorzSlider(ResIDT BasePictRes, ResIDT SliderPictRes)
  566.     : Slider(BasePictRes, SliderPictRes)
  567.     {
  568.  
  569.     }
  570.  
  571.  
  572. // ---------------------------------------------------------------------------
  573. //        • HorzSlider(ResIDT BasePictRes, ResIDT mSliderPictRes, ResIDT SlideSelectPictRes))
  574. // ---------------------------------------------------------------------------
  575. //     Create Horizontal Slider and assign Pict resource numbers
  576.  
  577. HorzSlider::HorzSlider(ResIDT BasePictRes, ResIDT SliderPictRes, ResIDT SlideSelectPictRes)
  578.     : Slider(BasePictRes, SliderPictRes, SlideSelectPictRes)
  579.     {
  580.  
  581.     }
  582.  
  583.  
  584. // ---------------------------------------------------------------------------
  585. //        • HorzSlider(LStream*)
  586. // ---------------------------------------------------------------------------
  587. //    Construct HorzSlider from data in a Stream
  588.  
  589. HorzSlider::HorzSlider(LStream *inStream)
  590.     : Slider(inStream)
  591.     {
  592.  
  593.     }
  594.  
  595. // ---------------------------------------------------------------------------
  596. //        • CreateHorzSliderStream  [static]
  597. // ---------------------------------------------------------------------------
  598. //    Return a new HorzSlider object initialized using data from a Stream
  599.  
  600. HorzSlider *HorzSlider::CreateHorzSliderStream(LStream *inStream)
  601. {
  602.     return (new HorzSlider(inStream));
  603. }
  604.  
  605. // ---------------------------------------------------------------------------
  606. //        • ~HorzSlider
  607. // ---------------------------------------------------------------------------
  608. //    Destructor, deletes any LGWorld objects created
  609.  
  610. HorzSlider::~HorzSlider()
  611. {
  612.  
  613. }
  614.  
  615.  
  616. // ---------------------------------------------------------------------------
  617. //        • TrackSlider
  618. // ---------------------------------------------------------------------------
  619. //    Move slider while mouse button is down
  620. //  Calls DoAction() when moving
  621.  
  622.  
  623. void HorzSlider::TrackSlider(Point oldMouse)
  624. {
  625.     Point newMouse;
  626.     mSelected = true;
  627.     if (!mSliderCursor)
  628.         HideCursor();                            // Hide cursor if mSliderCursor is false
  629.     while (Button()) {
  630.         GetMouse(&newMouse);
  631.         if (!EqualPt(newMouse, oldMouse)) {
  632.             // Mouse moved?
  633.             if (((newMouse.h > mBasePictRect.left) || (mSliderRect.left > mBasePictRect.left))
  634.                 && ((newMouse.h < mBasePictRect.right) || (mSliderRect.right < mBasePictRect.right))) {
  635.  
  636.                 // Move slider if mouse within base picture area
  637.                 OffsetRect(&mSliderRect, newMouse.h - oldMouse.h, 0);
  638.  
  639.                 // Keep Slider from going too far
  640.                 if (mSliderRect.right > mBasePictRect.right)
  641.                     OffsetRect(&mSliderRect, mBasePictRect.right - mSliderRect.right, 0);
  642.                 if (mSliderRect.left < mBasePictRect.left)
  643.                     OffsetRect(&mSliderRect, mBasePictRect.left - mSliderRect.left, 0);
  644.                 oldMouse = newMouse;
  645.                 DrawSelf();
  646.                 DoAction();                        // Send message
  647.                 FocusDraw();
  648.             }
  649.         }
  650.         oldMouse = newMouse;
  651.     }
  652.     mSelected = false;
  653.     DrawSelf();                                    // Display again without selection
  654.     ShowCursor();                                // Display cursor in case it was hidden
  655. }
  656.  
  657.  
  658. // ---------------------------------------------------------------------------
  659. //        • ClickSelf
  660. // ---------------------------------------------------------------------------
  661. //    Move slider while mouse button is down
  662. //  Calls DoAction() when moving
  663.  
  664. void HorzSlider::ClickSelf(const SMouseDownEvent &inMouseDown)
  665. {
  666.     if (PointInSlider(inMouseDown.whereLocal)) {
  667.         // click in slider?
  668.         FocusDraw();
  669.         mSelected = true;
  670.         DrawSelf();                                // update as selected
  671.  
  672.         TrackSlider(inMouseDown.whereLocal);
  673.  
  674.     } else {
  675.         if (PtInRect(inMouseDown.whereLocal, &mBasePictRect)&&(!mSliderOnly)) {
  676.             // click in base?
  677.  
  678.             // Move Slider to center on mouse
  679.             OffsetRect(&mSliderRect, (inMouseDown.whereLocal.h - mSliderRect.left - 
  680.             ((mSliderRect.right - mSliderRect.left)  / 2)), 0);
  681.  
  682.             // Keep slider in base pict
  683.             if (mSliderRect.right > mBasePictRect.right)
  684.                 OffsetRect(&mSliderRect, mBasePictRect.right - mSliderRect.right, 0);
  685.             if (mSliderRect.left < mBasePictRect.left)
  686.                 OffsetRect(&mSliderRect, mBasePictRect.left - mSliderRect.left, 0);
  687.  
  688.             mSelected = true;
  689.             FocusDraw();
  690.             DrawSelf();
  691.             DoAction();                            // Send message
  692.  
  693.             // now track it
  694.             FocusDraw();
  695.             TrackSlider(inMouseDown.whereLocal);
  696.         }
  697.  
  698.     }
  699.  
  700. }
  701.  
  702. // ---------------------------------------------------------------------------
  703. //        • GetSliderValue    ( !!! MODIFIED !!! )
  704. // ---------------------------------------------------------------------------
  705. //    Return value of slider
  706.  
  707. long HorzSlider::GetSliderValue(void)
  708. {
  709.     long total;
  710.       float tempvalue;
  711.     total = (mMaxSliderValue - mMinSliderValue);
  712. //    tempvalue = ((float)total / (float)(mBaseLength)) *        
  713. //                (mSliderRect.left - mBasePictRect.left);      // Original
  714.     tempvalue = ((float)total / (float)(mBaseLength)) *
  715.                 (mSliderRect.left - mBasePictRect.left + 1);  // TE 8/31/95
  716.        return (tempvalue + mMinSliderValue);
  717.  
  718. }
  719.  
  720.  
  721. // ---------------------------------------------------------------------------
  722. //        • SetSliderValue
  723. // ---------------------------------------------------------------------------
  724. //    Set value of slider, update display and send message
  725.  
  726. void HorzSlider::SetSliderValue(long theValue)
  727. {
  728.     long total;
  729.       float tempvalue;
  730.     total = (mMaxSliderValue - mMinSliderValue);
  731.     if (theValue < mMinSliderValue)  theValue = mMinSliderValue;
  732.     if (theValue > mMaxSliderValue)  theValue = mMaxSliderValue;
  733.     tempvalue =    ((float)(theValue- mMinSliderValue)/(float)total)  * (mBaseLength);
  734.          OffsetRect(&mSliderRect,-mSliderRect.left,0);
  735.          OffsetRect(&mSliderRect,tempvalue,0);
  736.               FocusDraw();
  737.             DrawSelf();
  738.             DoAction();                            // Send message
  739.  
  740. }
  741.  
  742. // ---------------------------------------------------------------------------
  743. //        • VertSlider
  744. // ---------------------------------------------------------------------------
  745. //    Default Constructor
  746.  
  747. VertSlider::VertSlider()
  748.     : Slider()
  749.     {
  750.  
  751.     }
  752.  
  753. // ---------------------------------------------------------------------------
  754. //        • VertSlider(ResIDT BasePictRes, ResIDT SliderPictRes)
  755. // ---------------------------------------------------------------------------
  756. //     Create Vertical Slider and assign Pict resource numbers
  757.  
  758. VertSlider::VertSlider(ResIDT BasePictRes, ResIDT SliderPictRes)
  759.     : Slider(BasePictRes, SliderPictRes)
  760.     {
  761.  
  762.     }
  763.  
  764. // ---------------------------------------------------------------------------
  765. //        • VertSlider(ResIDT BasePictRes, ResIDT mSliderPictRes, ResIDT SlideSelectPictRes))
  766. // ---------------------------------------------------------------------------
  767. //     Create Vertical Slider and assign Pict resource numbers
  768.  
  769. VertSlider::VertSlider(ResIDT BasePictRes, ResIDT SliderPictRes, ResIDT SlideSelectPictRes)
  770.     : Slider(BasePictRes, SliderPictRes, SlideSelectPictRes)
  771.     {
  772.  
  773.     }
  774.  
  775. // ---------------------------------------------------------------------------
  776. //        • VertSlider(LStream*)
  777. // ---------------------------------------------------------------------------
  778. //    Construct VertSlider from data in a Stream
  779.  
  780. VertSlider::VertSlider(LStream *inStream)
  781.     : Slider(inStream)
  782.     {
  783.  
  784.     }
  785.  
  786. // ---------------------------------------------------------------------------
  787. //        • CreateVertSliderStream  [static]
  788. // ---------------------------------------------------------------------------
  789. //    Return a new VertSlider object initialized using data from a Stream
  790.  
  791. VertSlider *VertSlider::CreateVertSliderStream(LStream *inStream)
  792. {
  793.     return (new VertSlider(inStream));
  794. }
  795.  
  796. // ---------------------------------------------------------------------------
  797. //        • ~VertSlider
  798. // ---------------------------------------------------------------------------
  799. //    Destructor, deletes any LGWorld objects created
  800.  
  801.  
  802. VertSlider::~VertSlider()
  803. {
  804.  
  805. }
  806.  
  807.  
  808. // ---------------------------------------------------------------------------
  809. //        • TrackSlider
  810. // ---------------------------------------------------------------------------
  811. //    Move slider while mouse button is down
  812. //  Calls DoAction() when moving
  813.  
  814. void VertSlider::TrackSlider(Point oldMouse)
  815. {
  816.     Point newMouse;
  817.     mSelected = true;
  818.     if (!mSliderCursor)
  819.         HideCursor();
  820.     while (Button()) {
  821.         GetMouse(&newMouse);
  822.         if (!EqualPt(newMouse, oldMouse)) {
  823.             // Mouse moved?
  824.             if (((newMouse.v > mBasePictRect.top) || (mSliderRect.top > mBasePictRect.top)) && 
  825.             ((newMouse.v < mBasePictRect.bottom) || (mSliderRect.bottom < mBasePictRect.bottom))) {
  826.             
  827.                 // Move Slider if mouse in base picture area
  828.                 OffsetRect(&mSliderRect, 0, newMouse.v - oldMouse.v);
  829.                 if (mSliderRect.bottom > mBasePictRect.bottom)
  830.                     OffsetRect(&mSliderRect, 0, mBasePictRect.bottom - mSliderRect.bottom);
  831.                 if (mSliderRect.top < mBasePictRect.top)
  832.                     OffsetRect(&mSliderRect, 0, mBasePictRect.top - mSliderRect.top);
  833.  
  834.                 oldMouse = newMouse;
  835.                 DrawSelf();
  836.                 DoAction();                        //  Send message
  837.                 FocusDraw();
  838.             }
  839.         }
  840.         oldMouse = newMouse;
  841.     }
  842.     mSelected = false;
  843.     DrawSelf();                                    // update without selection
  844.     ShowCursor();                                // Show cursor in case it was hidden
  845. }
  846.  
  847. // ---------------------------------------------------------------------------
  848. //        • ClickSelf
  849. // ---------------------------------------------------------------------------
  850. //    Move slider while mouse button is down
  851. //  Calls DoAction() when moving
  852.  
  853. void VertSlider::ClickSelf(const SMouseDownEvent &inMouseDown)
  854. {
  855.     if (PointInSlider(inMouseDown.whereLocal)) {
  856.         // click in slider?
  857.         FocusDraw();
  858.         mSelected = true;
  859.         DrawSelf();
  860.         TrackSlider(inMouseDown.whereLocal);
  861.  
  862.     } else {
  863.         if (PtInRect(inMouseDown.whereLocal, &mBasePictRect)&&(!mSliderOnly)) {
  864.             // click in base?
  865.             FocusDraw();
  866.             mSelected = true;
  867.             OffsetRect(&mSliderRect, 0, (inMouseDown.whereLocal.v - mSliderRect.top - ((mSliderRect.bottom - mSliderRect.top
  868.                                                                                       ) / 2)));
  869.             if (mSliderRect.bottom > mBasePictRect.bottom)
  870.                 OffsetRect(&mSliderRect, 0, mBasePictRect.bottom - mSliderRect.bottom);
  871.             if (mSliderRect.top < mBasePictRect.top)
  872.                 OffsetRect(&mSliderRect, 0, mBasePictRect.top - mSliderRect.top);
  873.  
  874.  
  875.  
  876.             DrawSelf();
  877.             DoAction();
  878.  
  879.             // now track it
  880.             FocusDraw();
  881.             TrackSlider(inMouseDown.whereLocal);
  882.         }
  883.  
  884.     }
  885.  
  886. }
  887.  
  888. // ---------------------------------------------------------------------------
  889. //        • GetSliderValue
  890. // ---------------------------------------------------------------------------
  891. //    Return value of slider
  892.  
  893. long VertSlider::GetSliderValue(void)
  894. {
  895.     long total;
  896.      float tempvalue;
  897.     total = (mMaxSliderValue - mMinSliderValue);
  898.     tempvalue = ((float)total / (float)(mBaseHeight)) *  (mSliderRect.top - mBasePictRect.top);
  899.      return (tempvalue + mMinSliderValue);
  900.  
  901. }
  902.  
  903.  
  904. // ---------------------------------------------------------------------------
  905. //        • SetSliderValue
  906. // ---------------------------------------------------------------------------
  907. //    Set value of slider, update display and send message
  908.  
  909. void VertSlider::SetSliderValue(long theValue)
  910. {
  911.     long total;
  912.       float tempvalue;
  913.     total = (mMaxSliderValue - mMinSliderValue);
  914.     if (theValue < mMinSliderValue)  theValue = mMinSliderValue;
  915.     if (theValue > mMaxSliderValue)  theValue = mMaxSliderValue;
  916.  
  917.         tempvalue =    ((float)(theValue- mMinSliderValue)/(float)total) *  mBaseHeight;
  918.          OffsetRect(&mSliderRect,0,-mSliderRect.top);
  919.          OffsetRect(&mSliderRect,0,tempvalue);
  920.               FocusDraw();
  921.             DrawSelf();
  922.             DoAction();                            // Send message
  923.  
  924. }
  925.